package org.wabson.alfresco.translations;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class BundleChangesServlet extends HttpServlet
{
    public static final String BASE_VERSION_PARAM_NAME = "b";
    public static final String COMPARE_VERSION_PARAM_NAME = "c";
    public static final String COMPARE_PACKAGE_PARAM_NAME = "p";
    public static final String MODE_PARAM_NAME = "m";

    /**
     * 
     */
    private static final long serialVersionUID = -8257907161559122261L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException
    {
    	WebApplicationContext springContext = WebApplicationContextUtils
    			.getRequiredWebApplicationContext(getServletContext());
    	
        StringBuffer sb = new StringBuffer();

        String baseVersion = req.getParameter(BASE_VERSION_PARAM_NAME); // e.g. 'community-3.2r', 'enterprise-3.2.0r'
        String compareVersion = req.getParameter(COMPARE_VERSION_PARAM_NAME); // e.g. 'community-3.2r', 'enterprise-3.2.0r'
        String packageName = req.getParameter(COMPARE_PACKAGE_PARAM_NAME);
        String mode = req.getParameter(MODE_PARAM_NAME) != null ? req.getParameter(MODE_PARAM_NAME) : "all";
        
        resp.setContentType("text/html; charset=UTF-8");
        resp.setCharacterEncoding("UTF-8");
        
        if (packageName != null && !packageName.equals(""))
        {
            packageName = "-" + packageName;
        }
        
        String baseFile, compareFile;
        
        if (baseVersion != null)
        {
            String[] rcmpts = baseVersion.split("-");
            if (rcmpts.length != 2)
            {
                throw new ServletException("Bad version " + baseVersion);
            }
            baseFile = "alfresco-" + rcmpts[0] + (packageName == null ? "" : packageName) + "-messages-" + rcmpts[1] + ".jar";
        }
        else
        {
            throw new ServletException("Must specify base version");
        }
        
        if (compareVersion != null)
        {
            String[] rcmpts = compareVersion.split("-");
            if (rcmpts.length != 2)
            {
                throw new ServletException("Bad version " + compareVersion);
            }
            compareFile = "alfresco-" + rcmpts[0] + (packageName == null ? "" : packageName) + "-messages-" + rcmpts[1] + ".jar";
        }
        else
        {
            throw new ServletException("Must specify compare version");
        }
        
        String messagesPath = "";

        try
        {
	        BundleLoaderFactory factory = (BundleLoaderFactory) springContext.getBean("bundle-loader-factory");
	        BundleLoader l1 = factory.createLoader(compareFile, messagesPath);
	        BundleLoader l2 = factory.createLoader(baseFile, messagesPath);
	        
	        BundleGroupComparator gc = new BundleGroupComparator(l2, l1);
	        BundleGroupComparisonResult gcr = gc.compare(null, null, true);
	        
	        sb.append("<html>\r\n");
	        sb.append("<head>\r\n");
	        sb.append("<title>Compare " + baseVersion + " and " + compareVersion + (packageName != null && !packageName.equals("") ? " (package " + packageName.substring(1) + ")" : "") + "</title>\r\n");
	        sb.append("<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/screen.css\" />");
	        sb.append("</head>\r\n");
	        sb.append("<body>\r\n");
	        sb.append("<div class=\"header\">\r\n");
	        sb.append("<p class=\"title\"><a href=\"/\">Alfresco I18N Tools</a></p>\r\n");
	        sb.append("</div>\r\n");
	        sb.append("<div class=\"body\">\r\n");
	        sb.append("<h1>Compare " + baseFile + " and " + compareFile + (packageName != null && !packageName.equals("") ? " (package " + packageName.substring(1) + ")" : "") + "</h1>\r\n");
	
	        // Print summary
	        if (!gcr.isIdentical())
	        {
	        	/*
		        sb.append("<h2>Summary</h2>\r\n");
		        sb.append("<ul>");
		        sb.append("<li>Analysed " + gcr.getNumMessages() + " source messages in " + gcr.getNumBundles() + " files</li>");
		        sb.append("<li>Identified " + gcr.getNumMissingMessages() + " missing messages and " + gcr.getNumMissingBundles() + " missing files</li>");
		        sb.append("<li>Identified " + gcr.getNumExtraMessages() + " extra messages and " + gcr.getNumExtraBundles() + " extra files</li>");
		        sb.append("</ul>");
		        */
	        }
	        else
	        {
	        	sb.append("<p>No changes were found</p>");
	        }
	        
	        int i = 0;
	       
	       for (String bundle : gcr.getBundles())
	       {
	           int state = gcr.getBundleState(bundle);
	           
	           if (state == BundleGroupComparisonResult.BUNDLE_STATE_MISSING && mode.equals("all"))
	           {
	               //sb.append("<h2 class=\"bundle missing\">" + bundle + "</h2><p class="missing">Only in " + l1 + "</p>\r\n");
	               sb.append("<h2 class=\"bundle\">" + bundle + "</h2><p>Only in " + compareFile + "</p>\r\n");
	               sb.append("<p class=\"links\">Show in <a href=\"/bundle?j=" + compareFile + "&f=" + messagesPath + "/" + bundle + "\">" + compareFile + "</a></p>\n");
	           }
	           else if (state == BundleGroupComparisonResult.BUNDLE_STATE_EXTRA && mode.equals("all"))
	           {
	               //sb.append("<h2 class=\"bundle\">" + bundle + "</h2><p>Only in " + l2 + "</p>\r\n");
	               //sb.append("<h2 class=\"bundle\">" + bundle + "</h2><p>Extra bundle " + bundle + "</p>\r\n");
	               sb.append("<h2 class=\"bundle\">" + bundle + "</h2><p>Only in " + baseFile + "</p>\r\n");
	               sb.append("<p class=\"links\">Show in <a href=\"/bundle?j=" + baseFile + "&f=" + messagesPath + "/" + bundle + "\">" + baseFile + "</a></p>\n");
	           }
	           else // Messages are different
	           {
	               BundleComparisonResult bundleResult = gcr.getComparisonResult(bundle);
	               
	               if (bundleResult != null && !bundleResult.isEmpty())
	               {
	                   sb.append("<h2 class=\"bundle\">" + bundle + "</h2>\r\n");
	
	                   sb.append("<div id=\"" + i + "-results\">\r\n");
	                   sb.append("<table cellpadding=\"3\" cellspacing=\"0\" border=\"0\">\r\n");
	            	   sb.append("<tr>\r\n");
	            	   sb.append("<th></th><th>" + baseFile + "</th><th>" + compareFile + "</th>\r\n");
	            	   sb.append("</tr>\r\n");
	                   for (MessageComparisonResult propResult : bundleResult.getPropertyComparisons())
	                   {
	                	   if (mode.equals("all") || (propResult.getThisValue() != null && propResult.getCompareToValue() != null))
	                	   {
		                	   sb.append("<tr>\r\n");
		                       sb.append("<td><tt><strong>" + propResult.getPropertyName() + "</strong></tt></td>");
		                       if (propResult.getThisValue() != null)
		                       {
		                           sb.append("<td><tt>" + htmlChars(propResult.getThisValue()) + "</tt></td>\r\n");
		                       }
		                       else
		                       {
		                           sb.append("<td>Not set</td>\r\n");
		                       }
		                       if (propResult.getCompareToValue() != null)
		                       {
		                           sb.append("<td><tt>" + htmlChars(propResult.getCompareToValue()) + "</tt></td>\r\n");
		                       }
		                       else
		                       {
		                           sb.append("<td>Not set</td>\r\n");
		                       }
		                	   sb.append("</tr>\r\n");
	                	   }
	                   }
	                   sb.append("</table>\r\n");
	                   sb.append("<p class=\"links\">Show in <a href=\"/bundle?j=" + baseFile + "&f=" + messagesPath + "/" + bundleResult.getCompareToFilePath() + "\">" + baseFile + "</a> | \n");
	                   sb.append("<a href=\"/bundle?j=" + compareFile + "&f=" + messagesPath + "/" + bundleResult.getCompareToFilePath() + "\">" + compareFile + "</a></p>\n");
	                   sb.append("</div>\n");
	               }
	           }
	           i ++;
	       }
	       sb.append("</div>\r\n");
	       sb.append("</body>\r\n");
	       sb.append("</html>\r\n");
        }
        catch (BundleLoadingException e)
        {
            throw new ServletException("Unable to load package", e);
        }
       
       resp.getWriter().print(sb.toString());
    }
    
    private static String htmlChars(String input)
    {
        String output = (input != null ? input : "");
        output = output.replaceAll("<", "&lt;");
        output = output.replaceAll("<", "&lt;");
        output = output.replaceAll("\\\"", "&quot;");
        return output;
    }
    
}
